package br.com.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import br.com.beans.Convenio;
import br.com.beans.Especialidade;
import br.com.beans.ItemSaude;
import br.com.beans.TabelaPrecos;

/**
 * Classe de manipulacao de objetos persistidos via JPA
 * Objetos da classe bean TabelaPrecos
 */
public class TabelaPrecosDAO extends GenericDAO<TabelaPrecos> {

	/**
	 * Localiza um item da Tabela de Precos persistido
	 * @param codConvenio Codigo do Convenio
	 * @param codEspecialidade Codigo da Especialidade
	 * @param codItemSaude Codigo do Item
	 * @return Objeto persistido
	 */
	public TabelaPrecos localizar(int codConvenio, int codEspecialidade, int codItemSaude) {

		EntityManager em = factory.createEntityManager();
		EntityTransaction t = em.getTransaction();
		TabelaPrecos obj = null;

		try {

			t.begin();
			Query query = em.createQuery("from TabelaPrecos where "
	                 + "codigoConvenio = :codConvenio and "
	                 + "codigoEspecialidade = :codEspecialidade and "
	                 + "codigoItemSaude = :codItemSaude");
			query.setParameter("codConvenio", codConvenio);
			query.setParameter("codEspecialidade", codEspecialidade);
			query.setParameter("codItemSaude", codItemSaude);
			obj = (TabelaPrecos) query.getSingleResult();
			t.commit();

		} catch (Exception e) {

			if (debugInfo) {
				e.printStackTrace();
			}
			if (t.isActive()) t.rollback();

		} finally {

			em.close();
		}

		return obj;
	}
	
	/**
	 * Lista itens da tabela de precos por parametro
	 * @param descConvenio Descricao do Convenio
	 * @param descEspecialidade Descricao da Especialidade
	 * @param descItemSaude Descricao do Item
	 * @return Lista de objetos persistidos
	 */
	@SuppressWarnings("unchecked")
	public List<TabelaPrecos> listar(String descConvenio, String descEspecialidade, String descItemSaude) {

		EntityManager em = factory.createEntityManager();
		EntityTransaction t = em.getTransaction();
		List<TabelaPrecos> list = null;

		ConvenioDAO      convenioDAO      = new ConvenioDAO();
		EspecialidadeDAO especialidadeDAO = new EspecialidadeDAO();
		ItemSaudeDAO     itemSaudeDAO     = new ItemSaudeDAO();

		Convenio convenio = convenioDAO.localizar(descConvenio);
		Especialidade especialidade = especialidadeDAO.localizar(descEspecialidade);
		ItemSaude itemSaude = itemSaudeDAO.localizar(descItemSaude);
		
		int codConvenio      = (convenio      != null) ? convenio.getCodigo()     : 0;
		int codEspecialidade = (especialidade != null) ? especialidade.getCodigo(): 0;
		int codItemSaude     = (itemSaude     != null) ? itemSaude.getCodigo()    : 0;

		try {

			t.begin();

			String queryString = "from TabelaPrecos";
			boolean whereQuery = false;
			boolean andQuery   = false;

			whereQuery = (codConvenio != 0 || codEspecialidade != 0 || codItemSaude != 0);

			if (whereQuery){
				queryString += " where";
				if (codConvenio != 0){
					queryString += " codigoConvenio = :codConvenio";
					andQuery = true;
				}
				if (codEspecialidade != 0){
					if (andQuery) queryString += " and";
					queryString += " codigoEspecialidade = :codEspecialidade"; 
					andQuery = true;
				}
				if (codItemSaude != 0){
					if (andQuery) queryString += " and";
					queryString += " codigoItemSaude = :codItemSaude";
				}
			}
		
			Query q = em.createQuery(queryString);

			if (codConvenio      != 0) q.setParameter("codConvenio"     , codConvenio);
			if (codEspecialidade != 0) q.setParameter("codEspecialidade", codEspecialidade);
			if (codItemSaude     != 0) q.setParameter("codItemSaude"    , codItemSaude);
			
			list = (List<TabelaPrecos>) q.getResultList();
			t.commit();

		} catch (Exception e) {

			if (debugInfo) {
				e.printStackTrace();
			}
			if (t.isActive()) t.rollback();

		} finally {

			em.close();
		}

		return list;
	}
	
	/**
	 * Retorna o valor de um item pesquisando na Tabela de Precos
	 * @param codConvenio Codigo do Convenio
	 * @param codEspecialidade Codigo da Especialidade
	 * @param codItemSaude Codigo do Item
	 * @return Objeto persistido
	 */
	public float getValor(int codConvenio, int codEspecialidade, int codItemSaude) {

		EntityManager em = factory.createEntityManager();
		EntityTransaction t = em.getTransaction();
		Query query = null;
		TabelaPrecos itemTabela = null;

		try {
			/* procura pelo item no convenio e especialidade */
			t.begin();
			query = em.createQuery("from TabelaPrecos where "
	                 + "codigoConvenio = :codConvenio and "
	                 + "codigoEspecialidade = :codEspecialidade and "
	                 + "codigoItemSaude = :codItemSaude");
			query.setParameter("codConvenio", codConvenio);
			query.setParameter("codEspecialidade", codEspecialidade);
			query.setParameter("codItemSaude", codItemSaude);
			itemTabela = (TabelaPrecos) query.getSingleResult();
			t.commit();
		} catch (Exception e) {
			if (t.isActive()) t.rollback();
			itemTabela = null;
		}
		
		if (itemTabela != null) {
			return itemTabela.getValor();
		}
		
		try {
			/* procura pelo item no convenio para todas especialidades */
			t.begin();
			query = em.createQuery("from TabelaPrecos where "
	                 + "codigoConvenio = :codConvenio and "
	                 + "codigoEspecialidade = null and "
	                 + "codigoItemSaude = :codItemSaude");
			query.setParameter("codConvenio", codConvenio);
			query.setParameter("codItemSaude", codItemSaude);
			itemTabela = (TabelaPrecos) query.getSingleResult();
			t.commit();
		} catch (Exception e) {
			if (t.isActive()) t.rollback();
			itemTabela = null;
		}
		
		if (itemTabela != null) {
			return itemTabela.getValor();
		}
		
		try {
			/* procura pelo item na especialidade para todos convenios */
			t.begin();
			query = em.createQuery("from TabelaPrecos where "
	                 + "codigoConvenio = null and "
	                 + "codigoEspecialidade = :especialidade and "
	                 + "codigoItemSaude = :codItemSaude");
			query.setParameter("codEspecialidade", codEspecialidade);
			query.setParameter("codItemSaude", codItemSaude);
			itemTabela = (TabelaPrecos) query.getSingleResult();
			t.commit();
		} catch (Exception e) {
			if (t.isActive()) t.rollback();
			itemTabela = null;
		}
		
		if (itemTabela != null) {
			return itemTabela.getValor();
		}

		try {
			/* procura pelo item para todos convenios e especialidades */
			t.begin();
			query = em.createQuery("from TabelaPrecos where "
	                 + "codigoConvenio = null and "
	                 + "codigoEspecialidade = null and "
	                 + "codigoItemSaude = :codItemSaude");
			query.setParameter("codItemSaude", codItemSaude);
			itemTabela = (TabelaPrecos) query.getSingleResult();
			t.commit();
		} catch (Exception e) {
			if (t.isActive()) t.rollback();
			itemTabela = null;
		}
		
		if (itemTabela != null) {
			return itemTabela.getValor();
		}
		
		em.close();

		/* nao achou, retorna 0 */
		return 0.0f;
	}

}
